import React, { Component } from 'react';
import 'styles/expense/expense-invoice.scss';
import INVOICE_MAP from '../service/invoice-service';
import { currencyPrecisionCal, messages, queryCurrencyPrecision, deepCopy, mulCalculate } from 'share/common';
import {
  Button,
  Col,
  DatePicker,
  Form, Icon,
  Input,
  InputNumber,
  message,
  Modal,
  notification,
  Popover,
  Row,
  Select,
  Spin,
  Table
} from 'antd';
import Condition from 'components/condition';
import ReceiptChangeIcon from '../svg-component/receipt-change';
import doubt from 'images/expense-detail/doubt.png';
import expenseService from '../../my-account/expense.service';
import { connect } from 'react-redux';
import Selector from 'components/selector';
import moment from 'moment';
import dataSources from '../../my-account/data-sources/data-sources';
import newExpenseService from '../expense-service';
import invoiceBagApproveService from '../../financial-management/invoice-bag-approve/invoice-bag-approve.service';
import { auditSaveReceipt, shouldChangeFeeAutomatic } from '../../my-account/components/common-method';
import cmbcEn from 'images/expense-detail/cmbc-en.png';
import cmbc from 'images/expense-detail/cmbc.png';
import alipayEn from 'images/expense-detail/alipay-en.png';
import alipay from 'images/expense-detail/alipay.png';
import huabeiEn from 'images/expense-detail/huabei-en.png';
import huabei from 'images/expense-detail/huabei.png';
import wechatIcon from 'images/expense/icon-wechat.png';
import alipayIcon from 'images/expense/icon-alipay.png';
import handIcon from 'images/expense/icon-hand.png';
import scanIcon from 'images/expense/icon-scan.png';
import ocrIcon from 'images/expense/icon-ocr.png';
import mailIcon from 'images/expense/icon-mail.png';
import didi from 'images/expense/icon-didi.png';
import ReceiptAmountMsg from '../../my-account/components/receipt-amount-msg';
import ImageUpload from 'components/image-upload'
import IeImgUpload from 'components/template/ie-file-upload/ie-img-upload'
import errorMessage from 'share/errorMessage';

const { Item } = Form;
const { If, Else } = Condition;
const { Option } = Select;
const { showUserInfoOptions, internalOptions, agentTagOptions, domesticPassengersOptions } = dataSources;

@connect(mapStateToProps)
@Form.create()
class Invoice extends Component {

  static contextTypes = {
    currentExpense: React.PropTypes.object,
    expenseReport: React.PropTypes.object,
    isAuditEditable: React.PropTypes.bool,
    currentExpenseType: React.PropTypes.object,
  };

  static InvoiceGoods(props) {
    const { currentReceipt: { invoiceGoods, invoiceTypeNo, blockchain } } = props;
    const columns = [
        {
          title: messages('expense-1.key67')/*货物或应税劳务、服务名称*/,
          dataIndex: 'goodsName',
          width: '30%',
          render: goodsName => <div style={{
            wordWrap: 'break-word',
            wordBreak: 'break-word',
            whiteSpace: 'normal',
            overflow: 'hidden',
            textOverflow: 'ellipsis'
          }}>
            {goodsName || '-'}
          </div>
        },
        {
          title: messages('expense-1.key68')/*规格型号*/,
          dataIndex: 'vehicleType',
          render: vehicleType => vehicleType || '-'
        },
        {
          title: messages('common.unit')/*单位*/, dataIndex: 'unit'
        },
        {
          title: messages('common.number')/*数量*/, dataIndex: 'count'
        },
        {
          title: messages('common.price')/*单价*/,
          dataIndex: 'unitPrice',
          render: (unitPrice, item) => (Number(unitPrice) / 100).toFixed(queryCurrencyPrecision(item.vatInvoiceCurrencyCode))
        },
        {
          title: messages('common.amount')/*金额*/,
          dataIndex: 'amount',
          render: (amount, item) => (amount !== undefined && amount !== null) ? (Number(amount) / 100).toFixed(queryCurrencyPrecision(item.vatInvoiceCurrencyCode)) : '-'
        },
        {
          title: messages('expense-1.key69')/*税率*/,
          dataIndex: 'taxRateString',
          render: value => (value !== undefined && value !== null) ? (isNaN(value) ? value : `${value}%`) : '-'
        },
        {
          title: messages('common.tax')/*税额*/,
          dataIndex: 'taxPrice',
          render: (taxPrice, item) => (taxPrice !== undefined && taxPrice !== null) ?
            (isNaN(taxPrice) ? taxPrice : (Number(taxPrice) / 100).toFixed(queryCurrencyPrecision(item.vatInvoiceCurrencyCode))) : '-'
        }
      ],
      travelColumns = [
        {
          title: messages('expense-1.key70')/*项目名称*/,
          dataIndex: 'goodsName',
          width: '23%',
          render: goodsName => goodsName || '-'
        },
        {
          title: messages('expense-1.key71')/*车牌号*/,
          dataIndex: 'plateNumber',
          width: '13%',
          render: plateNumber => plateNumber || '-'
        },
        {
          title: messages('expense-1.key72')/*类型*/,
          dataIndex: 'carType',
          width: '8%',
          render: carType => carType || '-'
        },
        {
          title: messages('expense-1.key73')/*通行日期起*/,
          dataIndex: 'passDateFrom',
          width: '17%',
          render: passDateFrom => passDateFrom || '-'
        },
        {
          title: messages('expense-1.key74')/*通行日期至*/,
          dataIndex: 'passDateTo',
          width: '17%',
          render: passDateTo => passDateTo || '-'
        },
        {
          title: messages('common.amount')/*金额*/,
          dataIndex: 'amount',
          width: '8%',
          render: (amount, item) => (amount !== undefined && amount !== null) ? (Number(amount) / 100).toFixed(queryCurrencyPrecision(item.vatInvoiceCurrencyCode)) : '-'
        },
        {
          title: messages('expense-1.key69')/*税率*/,
          dataIndex: 'taxRateString',
          width: '8%',
          render: value => (value !== undefined && value !== null) ? (isNaN(value) ? value : `${value}%`) : '-'
        },
        {
          title: messages('common.tax')/*税额*/,
          dataIndex: 'taxPrice',
          width: '8%',
          render: (taxPrice, item) => (taxPrice !== undefined && taxPrice !== null) ?
            (isNaN(taxPrice) ? taxPrice : (Number(taxPrice) / 100).toFixed(queryCurrencyPrecision(item.vatInvoiceCurrencyCode))) : '-'
        }
      ];

    return (
      <section className="expense-invoice-goods">
        <div className="expense-invoice-goods-title">{messages('expense-1.key671')/*商品信息*/}</div>
        <Table
          size="small"
          style={{ margin: '12px 0' }}
          columns={invoiceTypeNo !== '14' ? columns : travelColumns}
          dataSource={invoiceGoods}
          rowKey={(record, index) => index}
          pagination={false}
          locale={{ emptyText: blockchain ? messages('expense-1.key672')/*区块链发票：国税局不支持查验，无法获取发票行信息*/ : messages('common.empty.text')/*暂无数据*/ }}
        />
      </section>
    );
  }

  static InvoiceLabels(props) {
    const { labels = [], receiptChanges = {}, pdfDamaged, receiptLabelsDesc = [] } = props;
    let jsx_map = labels
      .map(item => (
        <div className="expense-invoice-tag-mar">
          <span className="expense-invoice-tag">
            <If value={item.type === 'MODIFY_RECEIPT'}><span
              className="expense-invoice-change"/></If>
            {item.name}
          </span>
        </div>)
      );
    pdfDamaged && jsx_map.push(<span
      className="expense-invoice-tag">{messages('expense-1.key212')/*电子票来源中的原件已损坏*/}</span>);
    receiptLabelsDesc[0] && jsx_map.push(<Invoice.InvoiceLabelsDesc
      receiptLabelsDesc={receiptLabelsDesc} receiptChanges={receiptChanges}/>);
    return (<div className="expense-invoice-tags"> {jsx_map[0] ? jsx_map : null}</div>);
  }

  static InvoiceLabelsDesc(props) {
    const { receiptChanges, receiptLabelsDesc } = props;
    const columns = [
      {
        title: messages('expense-1.key669')/*标签名称*/,
        dataIndex: 'name',
        render: value => value
      },
      {
        title: messages('expense-1.key102')/*标签说明*/,
        dataIndex: 'description',
        render: (value, record) => (
          <Condition>
            <If
              value={record.type === 'MODIFY_RECEIPT'}> {messages('expense-1.key670', { arg1: Object.keys(receiptChanges).length })/*共{arg1}处改动，详细见 “_ _ _”*/}</If>
            <Else>
              <div>
                <div>{record.toast}</div>
                <div>{(record.moreDesc || '').split('\n')
                  .map(item => <div>{item}</div>)}</div>
              </div>
            </Else>
          </Condition>
        )
      }
    ];
    return (
      <Popover
        content={
          <Table
            pagination={false}
            size={'small'}
            rowKey={'type'}
            columns={columns}
            dataSource={receiptLabelsDesc}
          />}
      >
        <span className="expense-invoice-tag expense-invoice-icon"><ReceiptChangeIcon/></span>
      </Popover>
    );

  }

  static isFieldDisabled(receipt, itemName) {
    //支付宝、微信来源发票
    const types = ['ALICARDSIGN', 'APPCARDSIGN', 'JSCARDSIGN', 'WXFWCARDSIGN'];
    //区块链发票的校验码有值时不可编辑
    if (receipt.blockchain && itemName === 'checkCode') {
      return !!receipt.checkCode;
    }
    //扫一扫
    if (receipt.cardsignType === 'SCANNING') {
      // 增值税卷式发票
      if (['11'].includes(receipt.invoiceTypeNo)) {
        return ['invoiceTypeNo', 'billingCode', 'billingNo'].includes(itemName);
      }
      // 增值税发票、机动车销售发票
      else if (['01', '03'].includes(receipt.invoiceTypeNo)) {
        return ['invoiceTypeNo', 'billingCode', 'billingNo', 'billingTime'].includes(itemName);
      }
      // 横版增值税发票
      else if (['04', '10', '14'].includes(receipt.invoiceTypeNo)) {
        return ['invoiceTypeNo', 'billingCode', 'billingNo', 'billingTime', 'checkCode'].includes(itemName);
      }
    } else {
      types.includes(receipt.cardsignType);
    }
  }

  static invoiceAttachmentInfo(configValue, type) {
    switch (type) {
      case 'extra':
        let supportType = configValue === '40' ? 'PDF/OFD' : 'PNG/JPG/JPEG/PDF/OFD';
        return `${messages('expense-1.key245')/*支持格式*/}: ${supportType}`;
      case 'fileType':
        return configValue === '40' ? ['pdf', 'ofd'] : ['jpg', 'png', 'jpeg', 'pdf', 'ofd'];
      case 'accept':
        return configValue === '40' ? 'application/pdf,.ofd' : 'image/*,application/pdf,.ofd';
    }
  }

  static InvoiceOrigin(props) {
    const { origin, language } = props;
    const bussiness = {
      CMBC: {
        'en': cmbcEn,
        'zh_cn': cmbc
      },
      ALIPAY: {
        'en': alipayEn,
        'zh_cn': alipay
      },
      HUABEI: {
        'en': huabeiEn,
        'zh_cn': huabei
      }
    };
    const originMap = {
      'APPCARDSIGN': wechatIcon,
      'JSCARDSIGN': wechatIcon,
      'WXFWCARDSIGN': wechatIcon,
      'ALICARDSIGN': alipayIcon,
      'HAND': handIcon,
      'SCANNING': scanIcon,
      'OCR': ocrIcon,
      'MAIL': mailIcon,
      'DIDI': didi,
      'CMBC': bussiness.CMBC[language.code] || bussiness.CMBC['en'],
      'ALIPAY': bussiness.ALIPAY[language.code] || bussiness.ALIPAY['en'],
      'HUABEI': bussiness.HUABEI[language.code] || bussiness.HUABEI['en']
    };
    return (
      <div className="expense-invoice-origin">{messages('common.from')/*来源*/} <img
        src={originMap[origin] || handIcon} className="expense-invoice-icon"/></div>
    );
  }

  /**
   * @name 字段映射(配置中心返回的字段与发票实体本身的字段对不上)
   * @type {{priceTaxAmount: string, nonVATinclusiveAmount: string, owner: string, image: string, internal: string, issuedReceipt: string, invoiceNumber: string, invoiceDate: string, taxAmount: string, invoiceCode: string, personInfo: string}}
   */
  static  receipt_config_Map = {
    image: 'slicingAttachmentOID',
    invoiceCode: 'billingCode',
    invoiceNumber: 'billingNo',
    invoiceDate: 'billingTime',
    priceTaxAmount: 'fee',
    taxAmount: 'tax',
    nonVATinclusiveAmount: 'feeWithoutTax',
    owner: 'receiptOwner',
    personInfo: 'showUserInfo',
    internal: 'internalStaff',
    issuedReceipt: 'agentTag'
  };

  /**
   * @name 字段控件映射
   * @type {{vatInvoiceCurrencyCode: Selector, feeWithoutTax: InputNumber, agentTag: Select, showUserInfo: Select, fee: InputNumber, billingTime: DatePickerDecorator, tax: InputNumber, invoiceTypeNo: Selector, taxRate: Selector, totalAmount: InputNumber, default: Input, internalStaff: Select, nonDeductibleAmount: InputNumber, domesticPassengers: Select}}
   */
  static  components_map = {
    'invoiceTypeNo': Selector,
    'billingTime': DatePicker,
    'taxRate': Selector,
    'vatInvoiceCurrencyCode': Selector,
    'totalAmount': InputNumber,
    'fee': InputNumber,
    'nonDeductibleAmount': InputNumber,
    'tax': InputNumber,
    'feeWithoutTax': InputNumber,
    'showUserInfo': Select,
    'internalStaff': Select,
    'agentTag': Select,
    'domesticPassengers': Select,
    'default': Input,
    'slicingAttachmentOID': window.ISIE9 ? IeImgUpload : ImageUpload
  };

  constructor(props, context) {
    super(props, context);
    this.state = {
      isEditing: false, // 是否是编辑状态
      buttonLoading: false,
      companyOpenInvoice: false,
      formMap: { // form表单
        invoiceTypeNo: {
          component: Selector,
          rules: [{
            required: true,
            message: messages('common.select')/*请选择*/
          }],
          props: {
            allowClear: false,
            disabled: false,
            type: 'receipt_type',
            placeholder: messages('common.select')/*请选择*/,
            params:{
              userOID: context.expenseReport.applicantOID
            },
            onChange: this.handleReceiptNoChange,
          }
        },
        default: {
          component: Input,
          props: {
            placeholder: messages('common.please.input'),/*请输入*/
          }
        }
      },
      receiptTipImages: {},
      additionalRecordingPriceAmountConfig: false,
      recordTaxRateConfig: false
    };

    this.receiptConfigMap = { // 发票字段form映射
      invoiceTypeNo: () => {
        return {
          rules: [{
            required: true,
            message: messages('common.select')/*请选择*/
          }],
          props: {
            disabled: false,
            type: 'receipt_type',
            placeholder: messages('common.select')/*请选择*/,
            onChange: this.handleReceiptNoChange,
            params:{
              userOID: context.expenseReport.applicantOID
            }
          }
        };
      },
      slicingAttachmentOID: () => {
        const { currentAdjunct: { slicingAttachment } } = props;
        return {
          props: {
            defaultFileList: slicingAttachment && [slicingAttachment] || [],
            attachmentType: 'INVOICE_IMAGES',
            showFileName: false,
            maxNum: 1,
            isUploading: value => this.setState({ imageIsUploading: value })
          }
        };
      },
      billingCode: () => {
        return {
          rules: [
            {
              max: 50,
              message: messages('common.max.characters.length', { arg1: 50 })/*最多输入{arg1}个字符*/
            }, {
              validator: (rule, value, callback) => {
                if (/^[A-Za-z0-9]{0,50}$/.test(value)) {
                  callback();
                } else {
                  callback(messages('expense-1.key167')/*请输入字母或数字*/);
                }
              }
            }
          ],
          props: {
            disabled: false,
            placeholder: messages('expense-1.key56')/*请输入temp2*/
          }
        };
      },
      billingNo: () => {
        return {
          rules: [
            {
              max: 50,
              message: messages('common.max.characters.length', { arg1: 50 })/*最多输入{arg1}个字符*/
            }, {
              validator: (rule, value, callback) => {
                if (/^[A-Za-z0-9]{0,50}$/.test(value)) {
                  callback();
                } else {
                  callback(messages('expense-1.key167')/*请输入字母或数字*/);
                }
              }
            }
          ],
          props: {
            disabled: false,
            placeholder: messages('expense-1.key56')/*请输入temp2*/
          }
        };
      },
      billingTime: () => {
        return {
          props: {
            placeholder: messages('common.select'),/*请选择*/
            disabledDate: this.disabledDate,
            disabled: false
          }
        };
      },
      taxRate: () => {
        const { currentAdjunct: { invoiceTypeNo } } = this.props;
        const { recordTaxRateConfig } = this.state;
        const currentInvoiceTypeNo = this.getFormItemValue('invoiceTypeNo') || invoiceTypeNo;
        return {
          props: {
            placeholder: messages('common.select'),/*请选择*/
            onChange: this.handleChangeTaxRate,
            type: 'tax_type',
            params: { receiptValue: currentInvoiceTypeNo },
            disabled: recordTaxRateConfig,
            allowClear: false,
            getPopupContainer: () => this.refs.invoiceForm,
          },
          hide: recordTaxRateConfig,
          depend: ['invoiceTypeNo', 'resultCode'],
          invoiceTypeNo: ['props-params'],
          resultCode: ['hide']
        };
      },
      vatInvoiceCurrencyCode: () => {
        const { user } = this.props;
        return {
          props: {
            placeholder: messages('common.select'),/*请选择*/
            onChange: this.selectVatInvoiceCurrencyCodeChange,
            type: 'currency',
            allowClear: false,
            params: {
              language: 'zh_cn',
              userOId: user.userOID,
              enable: true,
              withRate: false
            },
            getPopupContainer: () => this.refs.invoiceForm
          }
        };
      },
      totalAmount: () => {
        const { currentAdjunct: { vatInvoiceCurrencyCode, invoiceTypeNo } } = this.props;
        const vatInvoiceCurrencyCodeValue = this.getFormItemValue('vatInvoiceCurrencyCode') || vatInvoiceCurrencyCode;
        let currentInvoiceTypeNo = this.getFormItemValue('invoiceTypeNo') || invoiceTypeNo;
        const currencyPrecision = queryCurrencyPrecision(vatInvoiceCurrencyCodeValue);
        typeof currentInvoiceTypeNo === 'object' && (currentInvoiceTypeNo = currentInvoiceTypeNo.value);
        return {
          props: {
            precision: currencyPrecision,
            step: currencyPrecision ? 1 / Math.pow(10, currencyPrecision) : 1,
            placeholder: messages('expense-1.key168'),/*行程单“合计”*/
            onChange: value => this.handleAmountLinkage('totalAmount', value)
          },
          hide: !['150', '170'].includes(currentInvoiceTypeNo),
          depend: ['vatInvoiceCurrencyCode', 'invoiceTypeNo'],
          vatInvoiceCurrencyCode: ['props-precision', 'props-display'],
          invoiceTypeNo: ['hide']
        };
      },
      fee: () => {
        const { currentAdjunct: { vatInvoiceCurrencyCode } } = this.props;
        const { additionalRecordingPriceAmountConfig } = this.state;
        const vatInvoiceCurrencyCodeValue = this.getFormItemValue('vatInvoiceCurrencyCode') || vatInvoiceCurrencyCode;
        const currencyPrecision = queryCurrencyPrecision(vatInvoiceCurrencyCodeValue);
        return {
          props: {
            placeholder: messages('common.please.input'),/*请输入*/
            precision: currencyPrecision,
            step: currencyPrecision ? 1 / Math.pow(10, currencyPrecision) : 1,
            onChange: value => this.handleAmountLinkage('fee', value)
          },
          hide: additionalRecordingPriceAmountConfig,
          depend: ['vatInvoiceCurrencyCode', 'resultCode'],
          vatInvoiceCurrencyCode: ['props-precision', 'props-display'],
          resultCode: ['hide']
        };
      },
      nonDeductibleAmount: () => {
        const { currentAdjunct: { vatInvoiceCurrencyCode, invoiceTypeNo } } = this.props;
        const vatInvoiceCurrencyCodeValue = this.getFormItemValue('vatInvoiceCurrencyCode') || vatInvoiceCurrencyCode;
        const currentInvoiceTypeNo = this.getFormItemValue('invoiceTypeNo') || invoiceTypeNo;
        const currencyPrecision = queryCurrencyPrecision(vatInvoiceCurrencyCodeValue);
        return {
          props: {
            placeholder: messages('common.please.input'),/*请输入*/
            precision: currencyPrecision,
            step: currencyPrecision ? 1 / Math.pow(10, currencyPrecision) : 1,
            disabled: !['150', '170'].includes(currentInvoiceTypeNo),
            onChange: value => this.handleAmountLinkage('nonDeductibleAmount', value)
          },
          hide: !['150', '170'].includes(currentInvoiceTypeNo),
          depend: ['vatInvoiceCurrencyCode', 'invoiceTypeNo'],
          vatInvoiceCurrencyCode: ['props-precision', 'props-step'],
          invoiceTypeNo: ['props-disabled']
        };
      },
      tax: () => {
        const { currentAdjunct: { vatInvoiceCurrencyCode } } = this.props;
        const vatInvoiceCurrencyCodeValue = this.getFormItemValue('vatInvoiceCurrencyCode') || vatInvoiceCurrencyCode;
        const currencyPrecision = queryCurrencyPrecision(vatInvoiceCurrencyCodeValue);
        return {
          props: {
            placeholder: messages('common.please.input'),/*请输入*/
            precision: currencyPrecision,
            step: currencyPrecision ? 1 / Math.pow(10, currencyPrecision) : 1,
            onChange: this.handleChangeTaxAmount
          },
          rules: [
            {
              validator: this.handleValidator
            }
          ],
          depend: 'vatInvoiceCurrencyCode',
          vatInvoiceCurrencyCode: ['props-precision', 'props-step'],
        };
      },
      feeWithoutTax: () => {
        const { currentAdjunct: { vatInvoiceCurrencyCode } } = this.props;
        const vatInvoiceCurrencyCodeValue = this.getFormItemValue('vatInvoiceCurrencyCode') || vatInvoiceCurrencyCode;
        const currencyPrecision = queryCurrencyPrecision(vatInvoiceCurrencyCodeValue);
        return {
          props: {
            placeholder: messages('common.please.input'),/*请输入*/
            precision: currencyPrecision,
            step: currencyPrecision ? 1 / Math.pow(10, currencyPrecision) : 1,
            onChange: this.handleChangeNonVATinclusiveAmount
          },
          rules: [
            {
              validator: this.handleValidator
            }
          ],
          depend: 'vatInvoiceCurrencyCode',
          vatInvoiceCurrencyCode: ['props-precision', 'props-step'],
        };
      },
      checkCode: () => {
        return {
          props: {
            maxLength: '6',
            placeholder: messages('common.please.input'),/*请输入*/
          },
          rules: [
            {
              min: 5,
              message: messages('expense-1.key169')/*请输入校验码后6位*/
            }, {
              max: 6,
              message: messages('expense-1.key169')/*请输入校验码后6位*/
            }, {
              pattern: '^[0-9a-zA-Z]{1,}$',
              message: messages('expense-1.key170')/*只支持数字和字母*/
            }
          ]
        };
      },
      receiptOwner: () => {
        return {
          rules: [
            {
              max: 50,
              message: messages('common.max.characters.length', { arg1: 50 })/*最多输入{arg1}个字符*/
            }
          ],
          props: {
            disabled: false,
            placeholder: messages('expense-1.key56')/*请输入temp2*/
          }
        };
      },
      idCardNo: () => {
        return {
          rules: [
            {
              max: 20,
              message: messages('common.max.characters.length', { arg1: 20 })/*最多输入{arg1}个字符*/
            },
            {
              validator: (rule, value, callback) => {
                if (value && !value.match('^[0-9a-zA-Z\*]*$')) {
                  callback(messages('expense-1.key173')/*只允许填写字母、数字或**/);
                }
                callback();
              }
            }
          ],
          props: {
            disabled: false,
            placeholder: messages('expense-1.key56')/*请输入temp2*/
          }
        };
      },
      showUserInfo: () => {
        return {
          props: {
            getPopupContainer: () => this.refs.invoiceForm,
            allowClear: true,
            optionLabelProp: 'title',
            placeholder: messages('common.select')/*请选择*/
          },
          children: showUserInfoOptions.map(item => (<Option key={item.key} title={item.title}
                                                             style={{ whiteSpace: 'normal' }}>{item.value}</Option>))
        };
      },
      internalStaff: () => {
        return {
          props: {
            getPopupContainer: () => this.refs.invoiceForm,
            allowClear: true,
            placeholder: messages('common.select')/*请选择*/
          },
          children: internalOptions.map(item => (<Option key={item.key}>{item.value}</Option>))
        };
      },
      agentTag: () => {
        return {
          props: {
            getPopupContainer: () => this.refs.invoiceForm,
            allowClear: true,
            placeholder: messages('common.select')/*请选择*/
          },
          children: agentTagOptions.map(item => (<Option key={item.key}>{item.value}</Option>))
        };
      },
      domesticPassengers: () => {
        return {
          props: {
            getPopupContainer: () => this.refs.invoiceForm,
            allowClear: true,
            placeholder: messages('common.select')/*请选择*/
          },
          children: domesticPassengersOptions.map(item => (
            <Option key={item.key}>{item.value}</Option>))
        };
      },
      default: () => {
        return {
          props: {
            placeholder: messages('common.please.input'),/*请输入*/
          },
          hide: true
        };
      }
    };

    this.depend = {}; // 组件关联依赖处理

    this.invoiceBase = deepCopy(props.invoiceBase);

    this.invoiceBase[0].unshift('slicingAttachmentOID', 'vatInvoiceCurrencyCode', 'taxRate', 'totalAmount', 'fee', 'nonDeductibleAmount', 'tax', 'feeWithoutTax'); // 编辑的时候加入字段
  };

  componentDidMount(){
    const { isEditing } = this.props;
    isEditing && this.handleEdit();
  }

  handleCancel = () => {
    this.setState({ isEditing: false });
  };

  handleEdit = async () => {
    this.setState({ buttonLoading: true });
    await this.getReceiptTitle();
    await Promise.all([this.getReceiptConfig(), this.getTipImg()]);
    this.setState({ buttonLoading: false, isEditing: true });
  };

  handleDelete = async () => {
    this.setState({ buttonLoading: true });
    const { currentAdjunct: invoice } = this.props;
    const params = {
      invoiceOID: invoice.invoiceOID,
      deleteReceiptIds: [invoice.id]
    };

    const callBack = (reviewResult) => {
      this.props.onInvoiceChange(invoice, 'DELETE', reviewResult);
      setTimeout(() => {
        this.setState({ buttonLoading: false });
      }, 300);
      return true
    };

    const onDefaultConfirm = async () => {
      await invoiceBagApproveService.deleteInvoice(invoice.id, invoice.invoiceOID);
      callBack();
    };

    await shouldChangeFeeAutomatic({
      type: 'DELETE',
      params,
      currentReceipt: invoice,
      validAuth: invoice.entityType === 'invoice',
      onConfirm: reviewResult => auditSaveReceipt(Object.assign({}, params, { reviewResult }), () => callBack(reviewResult), this),
      onDefaultConfirm,
      onCancel: () => { this.setState({ buttonLoading: false });}
    });
  };

  handlePrint = async () => {
    const { currentAdjunct: invoice } = this.props;
    const res = await expenseService.printInvoice(invoice.id);
    window.open(res.data.rows.fileURL, '_blank');
  };

  handleSave = () => {
    const { currentExpense: { invoiceOID, receiptList } } = this.context;
    this.props.form.validateFieldsAndScroll(async (err, values) => {
        if (!err) {
          try {
            this.setState({ buttonLoading: true });
            const res = await this.validatorInputMsg(values);
            const { user } = this.props;
            const { expenseReport = {} } = this.context;
            const result = await newExpenseService.testInvoice(res, user.userOID, 'invoice', expenseReport.expenseReportId, expenseReport.expenseReportOID, true, false);
            let receipt = await this.validatorTestMsg(result.data);
            const callBack = (receipt, reviewResult) => {
              this.props.onInvoiceChange(receipt, 'EDIT', reviewResult);
              setTimeout(() => {
                this.setState({ buttonLoading: false, isEditing: false });
              }, 500);
              return true;
            };
            const receipts = receiptList.map(rec => (rec.id === receipt.id && (rec = receipt) , rec));
            const params = { invoiceOID, receipts };
            shouldChangeFeeAutomatic({
              type: 'EDIT',
              params,
              currentReceipt: receipt,
              validAuth: true,
              onConfirm: async reviewResult => {
                const res = await auditSaveReceipt(Object.assign({}, params, { reviewResult }), () => callBack(receipt, reviewResult), this);
                !res && this.setState({ buttonLoading: false });
              },
              onCancel: () => this.setState({ buttonLoading: false }),
              onDefaultConfirm: async () => {
                try {
                  const res = await expenseService.financialAuditInvoice(receipt);
                  if (res.data.code === '0000') {
                    callBack(receipt);
                    message.success(messages('common.save.success', { arg1: '' })/*{arg1} 保存成功*/);
                  } else {
                    const errorList = res.data.rows.errorList;
                    const warningInfo = [];
                    errorList && errorList.length > 0 && errorList.map(item => {
                      warningInfo.push(`${item.title}${item.title ? ':' : ''}${item.message}`);
                    });
                    message.error(warningInfo.join('/'));
                  }
                } catch (e) {
                  errorMessage(e.response);
                }
                this.setState({ buttonLoading: false });
              }
            });
          }
          catch (e) {
            this.setState({ buttonLoading: false });
          }
        }
      }
    );
  };

  isEdit = () => {
    const { currentAdjunct: invoice } = this.props;
    const { isAuditEditable } = this.context;
    if (invoice.receiptLabels.some(item => item.type === 'DUPLICATE_INVOICE') || this.disableEdit() || !isAuditEditable) return false;
    return ((invoice.checkResult !== 'R_0000' || invoice.editable) && !~['DIDI'].indexOf(invoice.cardsignType) || (invoice.checkResult === 'R_0000' && Object.keys(JSON.parse(invoice.moreInfo || '{}')).length > 0));
  };

  isPrint = () => {
    let invoiceFreePrint = false;
    const { currentAdjunct: invoice } = this.props;
    const { isAuditEditable } = this.context;
    let isFinancial = window.location.pathname.indexOf('financial-management') > -1;
    invoice.receiptLabels && invoice.receiptLabels.forEach(label => {
      label.type === 'INVOICE_FREE' && !isFinancial && (invoiceFreePrint = true);
    });
    return !invoiceFreePrint && invoice.pdfUrl && !invoice.pdfDamaged && invoice.id && isAuditEditable;
  };

  disableEdit = () => {
    const {  profile } = this.props;
    const { currentExpense: { readOnly, withReceipt, valid }, expenseReport, currentExpenseType: { messageKey } } = this.context;
    return (expenseReport.status === 1002 || expenseReport.status === 1003) && !valid && !(profile['er.disabled'] || profile['finance.audit.disabled']) && !(withReceipt && messageKey !== 'expense.type.didi' && !readOnly);
  };

  isDelete = () => {
    const { currentAdjunct: invoice } = this.props;
    const { isAuditEditable } = this.context;
    return isAuditEditable && !this.disableEdit() && !~['DIDI'].indexOf(invoice.cardsignType);
  };

  getFormItemValue = (params = [], transfer) => { // 获取表单值
    const { getFieldsValue, getFieldValue } = this.props.form;
    const values = {};
    if (typeof params === 'string') {
      return getFieldsValue()
        .hasOwnProperty(params) ? transfer ? transfer(getFieldValue(params)) : getFieldValue(params) : '';
    }
    params.forEach(item => getFieldsValue()
      .hasOwnProperty(item) ? values[item] = transfer ? transfer(getFieldValue(item)) : getFieldValue(item) : '');
    return values;
  };

  selectVatInvoiceCurrencyCodeChange = (currency) => {
    const callBack = () => this.props.form.setFieldsValue(this.getFormItemValue(['fee', 'tax', 'feeWithoutTax', 'totalAmount'], (value) => Number(currencyPrecisionCal(currency, value))));
    this.handleDepend('vatInvoiceCurrencyCode', callBack);
  };

  handleAmountLinkage = (type, value = 0) => {
    const { setFieldsValue, getFieldsValue } = this.props.form;
    const { fee = 0, totalAmount, nonDeductibleAmount = 0, vatInvoiceCurrencyCode } = getFieldsValue();
    let precision = queryCurrencyPrecision(vatInvoiceCurrencyCode);
    value = Number(isNaN(value) ? 0 : value);
    //若总金额为空，需要计算总金额
    if (!totalAmount && totalAmount !== 0 && type !== 'totalAmount') {
      if (type === 'fee') { //价税合计
        getFieldsValue().hasOwnProperty('totalAmount') && setFieldsValue({ totalAmount: (value + nonDeductibleAmount).toFixed(precision) });
        this.handleChangePriceTaxAmount(value);
      }
      if (type === 'nonDeductibleAmount') { //不可抵扣
        getFieldsValue().hasOwnProperty('totalAmount') && setFieldsValue({ totalAmount: (value + fee).toFixed(precision) });
      }
    } else {
      if (type === 'fee') { //价税合计
        setFieldsValue({ nonDeductibleAmount: (totalAmount - value).toFixed(precision) });
        this.handleChangePriceTaxAmount(value);
      }
      if (type === 'totalAmount') { //总金额
        setFieldsValue({ fee: (value - nonDeductibleAmount).toFixed(precision) });
        this.handleChangePriceTaxAmount(value - nonDeductibleAmount);
      }
      if (type === 'nonDeductibleAmount') { //不可抵扣
        setFieldsValue({ fee: (totalAmount - value).toFixed(precision) });
        this.handleChangePriceTaxAmount(totalAmount - value);
      }
    }
  };

  handleChangePriceTaxAmount = (amount) => {
    const { getFieldsValue, setFieldsValue, getFieldValue } = this.props.form;
    let taxRateValue = getFieldValue('taxRate');
    const taxRate = typeof taxRateValue === 'object' ? taxRateValue.taxRateValue : taxRateValue;
    let vatInvoiceCurrencyCodeValue = this.getFormItemValue('vatInvoiceCurrencyCode');
    let currencyPrecision = queryCurrencyPrecision(vatInvoiceCurrencyCodeValue);
    if (Number(taxRate) >= 0) {
      amount = parseFloat(amount);
      isNaN(amount) && (amount = 0);
      const feeWithoutTax = Number((amount / (1 + taxRate)).toFixed(currencyPrecision));
      let tax = Number((amount - feeWithoutTax).toFixed(currencyPrecision));
      getFieldsValue()
        .hasOwnProperty('feeWithoutTax') && setFieldsValue({ feeWithoutTax });
      getFieldsValue()
        .hasOwnProperty('tax') && setFieldsValue({ tax });
    }
  };

  handleChangeTaxRate = (value) => {
    const { getFieldsValue, setFieldsValue, getFieldValue } = this.props.form;
    let amount = getFieldValue('fee');
    let feeWithoutTax;
    getFieldsValue()
      .hasOwnProperty('feeWithoutTax') && (feeWithoutTax = getFieldValue('feeWithoutTax'));
    let vatInvoiceCurrencyCodeValue = this.getFormItemValue('vatInvoiceCurrencyCode');
    let currencyPrecision = queryCurrencyPrecision(vatInvoiceCurrencyCodeValue);
    if (Math.abs(Number(amount)) >= 0) {
      let feeWithoutTax = Number((amount / (1 + value)).toFixed(currencyPrecision));
      let tax = Number((amount - feeWithoutTax).toFixed(currencyPrecision));
      getFieldsValue()
        .hasOwnProperty('feeWithoutTax') && setFieldsValue({ feeWithoutTax: feeWithoutTax });
      getFieldsValue()
        .hasOwnProperty('tax') && setFieldsValue({ tax });
    } else if (feeWithoutTax) {
      let fee = Number(+feeWithoutTax * (1 + value))
        .toFixed(currencyPrecision);
      let taxAmount = Number((fee - feeWithoutTax).toFixed(currencyPrecision));
      getFieldsValue()
        .hasOwnProperty('fee') && setFieldsValue({ fee });
      getFieldsValue()
        .hasOwnProperty('taxAmount') && setFieldsValue({ taxAmount: taxAmount });
      setFieldsValue({ feeWithoutTax: this.getCurrencyPrecisionValue(feeWithoutTax) });
    }
  };

  handleReceiptNoChange = async (value) => {
    await Promise.all([this.getReceiptConfig(value), this.getTipImg(value)]);
    const { form: { getFieldsValue, setFieldsValue } } = this.props;
    const exitVar = {};
    const { invoiceTypeNo, nonDeductibleAmount, fee: totalAmount } = getFieldsValue();
    const defaultValueMap = { // 小票(0) 机票(50) 默认不可抵扣
      '170': 0,
      '150': 50
    };
    if (['170', '150'].includes(invoiceTypeNo)) {
      exitVar.nonDeductibleAmount = nonDeductibleAmount || defaultValueMap[invoiceTypeNo];
      exitVar.totalAmount = totalAmount;
      (totalAmount || totalAmount === 0) && (exitVar.fee = totalAmount - nonDeductibleAmount);
    }
    setFieldsValue(exitVar);
  };

  handleDepend = (code, callBack) => {
    if (!this.depend[code]) return;
    const { formMap } = this.state;
    setTimeout(() => {
      this.depend[code].map(item => {
        const replaceForm = this.receiptConfigMap[item]();
        for (let c of  replaceForm[code]) {
          const m = c.match(/(\w+)-(\w+)/);
          if (m) {
            formMap[item][m[1]][m[2]] = replaceForm[m[1]][m[2]];
            continue;
          }
          formMap[item][c] = replaceForm[c];
        }
      });
      this.setState({ formMap }, () => { callBack && callBack();});
    });
  };

  handleChangeTaxAmount = (value) => {
    const { getFieldsValue, setFieldsValue, getFieldValue } = this.props.form;
    let amount = getFieldValue('fee');
    //避免金额合计控件不显示，强行计算
    if (!getFieldsValue()
      .hasOwnProperty('feeWithoutTax')) {
      return;
    }
    let feeWithoutTax = amount - value;
    if (!isNaN(feeWithoutTax)) {
      setFieldsValue({ feeWithoutTax: this.getCurrencyPrecisionValue(feeWithoutTax) });
    }
  };

  handleChangeNonVATinclusiveAmount = (value) => {
    const { getFieldsValue, setFieldsValue, getFieldValue } = this.props.form;
    let currencyCode = this.getFormItemValue('vatInvoiceCurrencyCode');
    let precision = queryCurrencyPrecision(currencyCode);
    let amount = getFieldValue('fee');
    let tax = parseFloat((amount - value).toFixed(precision));
    if (!getFieldsValue()
      .hasOwnProperty('tax')) {
      return;
    }
    if (isNaN(tax)) {
      setFieldsValue({ tax: amount });
    } else {
      setFieldsValue({ tax });
    }
  };

  getCurrencyPrecisionValue = (value) => {
    let vatInvoiceCurrencyCodeValue = this.getFormItemValue('vatInvoiceCurrencyCode');
    let currencyPrecision = queryCurrencyPrecision(vatInvoiceCurrencyCodeValue);
    return Number(value)
      .toFixed(currencyPrecision);
  };

  disabledDate = (current) => {
    return current && current.valueOf() > Date.now();
  };

  handleValidator = (rule, value, callback) => {  // 处理报错
    const { getFieldValue } = this.props.form,
      priceTaxAmountValue = getFieldValue('fee'),
      arrSpeech = {};
    if (rule.field === 'taxAmount') {
      arrSpeech['speechOne'] = messages('expense-1.key160')/*税额合计的绝对值不能大于价税合计的绝对值*/;
      arrSpeech['speechTwo'] = messages('expense-1.key161')/*税额合计与价税合计的符号必须一致！*/;
    }
    if (rule.field === 'feeWithoutTax') {
      arrSpeech['speechOne'] = messages('expense-1.key162')/*金额合计(不含税)的绝对值不能大于价税合计的绝对值*/;
      arrSpeech['speechTwo'] = messages('expense-1.key163')/*金额合计(不含税)与价税合计的符号必须一致！*/;
    }
    if (Math.abs(value) > Math.abs(priceTaxAmountValue)) {  // 金额合计不能大于价税合计
      callback(arrSpeech['speechOne']);
    } else if (value > 0 && priceTaxAmountValue < 0 || priceTaxAmountValue > 0 && value < 0) {
      callback(arrSpeech['speechTwo']);
    } else {
      callback();
    }
  };

  getReceiptTitle = async () => {
    const { user } = this.props;
    const { expenseReport: { applicantOID } } = this.context;
    const title = await expenseService.getTitleList(applicantOID || user.userOID);
    await this.setState({ companyOpenInvoice: title.data.showCheckInvoiceFlag });
  };

  collectionDependency = (base, formDepend) => {
    if (typeof formDepend === 'string')
      this.depend[formDepend]
        ? !this.depend[formDepend].includes(base) && this.depend[formDepend].push(base)
        : this.depend[formDepend] = [base];
    if (typeof formDepend === 'object')
      formDepend.map(depend =>
        this.depend[depend]
          ? !this.depend[depend].includes(base) && this.depend[depend].push(base)
          : this.depend[depend] = [base]);
  };

  getTipImg = async (invoiceTypeNoValue = this.props.currentAdjunct.invoiceTypeNo) => {
    const { receiptTipImages } = this.state;
    if (receiptTipImages[invoiceTypeNoValue]) {
      return !1;
    }
    const res = await expenseService.getReceiptTipImg(invoiceTypeNoValue);
    receiptTipImages[invoiceTypeNoValue] = res.data;
    this.setState({ receiptTipImages });
  };

  getReceiptConfig = async (type) => {
    const { company, documentaryCompany, currentAdjunct: { invoiceTypeNo }, currentAdjunct } = this.props;
    const { companyOpenInvoice, formMap } = this.state;
    const companyForReceipt = documentaryCompany && documentaryCompany.id ? documentaryCompany : company;
    const res = await expenseService.getReceiptDisplay(companyOpenInvoice, type || invoiceTypeNo, companyForReceipt.tenantId, companyForReceipt.setOfBooksId, companyForReceipt.id);
    const receiptConfigList = JSON.parse(res.data.rows[0].hitValue);
    const enableEditKeys = ['receiptOwner', 'idCardNo', 'showUserInfo', 'internalStaff', 'agentTag', 'domesticPassengers'];
    const types = ['payee', 'payeeNo', 'title', 'draweeNo'];

    // 初始化form表单， 同时收集依赖信息
    this.invoiceBase.forEach(base => {
      base.forEach(item => {
        if (formMap[item] && (!formMap[item].depend || !formMap[item].depend.includes('invoiceTypeNo'))) return;
        formMap[item] = this.receiptConfigMap[item] ? this.receiptConfigMap[item]() : this.receiptConfigMap['default']();
        formMap[item].component = Invoice.components_map[item] || Invoice.components_map['default'];
        this.collectionDependency(item, formMap[item].depend);
      });
    });

    // 属于配置中心管控字段
    receiptConfigList.forEach(item => {
      const valueCode = Invoice.receipt_config_Map[item.valueCode] || item.valueCode;
      let form = formMap[valueCode] || { props: {} };
      form.required = item.value === '30';
      form.props.disabled = item.value === '10' || Invoice.isFieldDisabled(currentAdjunct, valueCode) || (currentAdjunct.checkResult === 'R_0000' && !currentAdjunct.alipayOrWeChat && !enableEditKeys.includes(valueCode));
      form.hide = item.value === '10' && !currentAdjunct[valueCode] && currentAdjunct[valueCode] !== 0;

      // 附件特殊处理
      if (valueCode === 'slicingAttachmentOID') {
        form.required = ['30', '40'].includes(item.value);
        form.props.fileType = Invoice.invoiceAttachmentInfo(item.value, 'fileType');
        form.props.accept = Invoice.invoiceAttachmentInfo(item.value, 'accept');
        form.extra = Invoice.invoiceAttachmentInfo(item.value, 'extra');
      }
    });

    formMap.invoiceTypeNo.props.disabled = currentAdjunct.checkResult === 'R_0000' && !currentAdjunct.alipayOrWeChat || Invoice.isFieldDisabled(currentAdjunct, 'invoiceTypeNo');

    // 特殊字段处理
    for (let t of types) {
      const f = formMap[t];
      if (!f) continue;
      f.props.disabled = currentAdjunct.checkResult === 'R_0000';
      f.hide = !types.some(item => currentAdjunct[item]);
    }

    // 特殊自定义字段，无需参与表单
    formMap.goodsName && (formMap.goodsName.hide = true);
    await this.setState({ formMap });
  };

  getInitialValue = (word) => {
    const { currentAdjunct, currentAdjunct: { invoiceTypeNo, type, taxRate, vatInvoiceCurrencyCode, billingTime, checkCode } } = this.props;
    if (['tax', 'feeWithoutTax', 'totalAmount', 'nonDeductibleAmount', 'fee'].includes(word)) {
      return (Number(currentAdjunct[word] || 0) / 100).toFixed(queryCurrencyPrecision(vatInvoiceCurrencyCode));
    }
    if (word === 'invoiceTypeNo') {
      return {
        messageKey: type,
        value: invoiceTypeNo
      };
    }
    if (word === 'taxRate') {
      return {
        taxRateKey: `${taxRate * 100}%`,
        taxRateValue: taxRate
      };
    }
    if (word === 'billingTime') {
      return billingTime ? moment(new Date(billingTime * 1000)) : void 0;
    }
    if (word === 'checkCode') {
      return checkCode ? checkCode.slice(-6) : checkCode;
    }
    return currentAdjunct[word];
  };

  validatorInputMsg = (values) => new Promise((res, rej) => {
    const { isDetail } = this.props,
      moreInfo = {},
      currentAdjunct = deepCopy(this.props.currentAdjunct),
      invoiceTypeNo = typeof values.invoiceTypeNo === 'object' ? values.invoiceTypeNo.value : values.invoiceTypeNo;

    if (!currentAdjunct.blockchain && invoiceTypeNo === '10' && values.checkCode && values.checkCode.length === 5) {
      Modal.info({ title: messages('expense-1.key157')/*增值税电子普通发票需输入校验码后六位数字。若票面仅有5位校验码，则为区块链发票，需要采用其他方式录入发票。*/ });
      rej(false);
      throw new Error(messages('expense-1.key157'));
    }

    if (!currentAdjunct.blockchain && values.checkCode && (!/^[0-9]+$/.test(values.checkCode) || values.checkCode.length !== 6)) {
      message.warning(messages('expense-1.key158')/*校验码仅支持6位数字*/);
      rej(false);
      throw new Error(messages('expense-1.key158'));
    }

    Object.keys(values)
      .forEach(item => {
        if (item.match(/^moreInfo-(\w+)$/)) {
          moreInfo[item.replace(/^moreInfo-(\w+)$/, '$1')] = values[item];
        } else {
          currentAdjunct[item] = values[item];
          if (item === 'slicingAttachmentOID') {
            const att = values[item];
            if (att && typeof att === 'object') {
              if ((att && att[0] && att[0].attachmentOID)) {
                if (['PDF', 'OFD'].includes(att[0].fileType)) {
                  currentAdjunct.attachmentOID = att[0].attachmentOID;
                  delete currentAdjunct.slicingAttachmentOID;
                } else {
                  currentAdjunct.slicingAttachmentOID = att[0].attachmentOID;
                }
              } else {
                currentAdjunct.slicingAttachment = null;
                currentAdjunct.slicingAttachmentOID = null;
              }
            }
          }

          item === 'invoiceTypeNo' && (currentAdjunct[item] = invoiceTypeNo);
          item === 'taxRate' && typeof values[item] === 'object' && (currentAdjunct[item] = values[item].taxRateValue);
          item === 'billingTime' && (currentAdjunct.billingTime = values.billingTime ? (new Date(values.billingTime).getTime() / 1000).toFixed(0) : null);
          ['tax', 'feeWithoutTax', 'totalAmount', 'nonDeductibleAmount', 'fee'].includes(item) && (currentAdjunct[item] = mulCalculate(values[item], 100));
        }
      });
    isDetail && (currentAdjunct.moreInfo = JSON.stringify(moreInfo));
    res(currentAdjunct);
  });

  validatorTestMsg = (result) => new Promise((res, rej) => {
    const { resultCode, msg, invoiceInfo, isOk, errorList } = result;
    if (isOk === 'N') {
      resultCode === 'R_2007' && this.setState({ additionalRecordingPriceAmountConfig: true });
      resultCode === 'R_2008' && this.setState({ additionalRecordingPriceAmountConfig: true, recordTaxRateConfig: true });
      resultCode === 'R_2002' && this.setState({ recordTaxRateConfig: true });
      this.handleDepend('resultCode');
      const messageFunc = invoiceInfo ? 'info' : 'error';
      msg && message[messageFunc](msg);
      errorList && errorList[0] && errorList.filter(e => e.level === 'ERROR')
        .forEach(e => {
          notification.open({
            message: e.title,
            description: e.message,
            icon: <Icon type="frown-circle" style={{ color: '#e93652' }}/>
          });
        });
      rej(false);
    }
    res(invoiceInfo);
  });

  handleShowUsedMsg = () => {
    const { currentExpense: { invoiceOID }, currentAdjunct: { id: receiptId } } = this.context;
    ReceiptAmountMsg.open({
      receiptId,
      invoiceOID
    }, this);
  };

  renderCell(props) {
    const { bodyWords = [], rowSpan = 12, colSpan = 8, isMoreInfo, moreInfo } = props;
    const currentAdjunct = isMoreInfo ? moreInfo : this.props.currentAdjunct;
    const { formMap, isEditing } = this.state;
    const { receiptChanges = {}, form: { getFieldDecorator } } = this.props;
    const formItemLayout = { labelCol: { span: 7 }, wrapperCol: { span: 15, offset: 1 }, };
    return <Row type={'flex'}>
      {
        bodyWords.map(item => {
          if (!isEditing) {
            if (item.isHide && item.isHide(currentAdjunct[item.dataIndex], currentAdjunct) || !item.name) return null;
            return (
              <Col span={rowSpan} className="adjunct-item-cell">
                <Row>
                  <Col span={colSpan} className="adjunct-item-cell-label">
                    {item.name}：
                  </Col>
                  <Col span={24 - colSpan}>
                    <div className={item.truthy && item.truthy(currentAdjunct[item.dataIndex], currentAdjunct) && 'adjunct-item-cell-error'}>
                      {item.render(currentAdjunct[item.dataIndex], currentAdjunct, receiptChanges[item.dataIndex])}
                    </div>
                    <If value={item.truthy && item.truthy(currentAdjunct[item.dataIndex], currentAdjunct)}>
                      <div className="adjunct-item-cell-truthy">
                        {item.truthy && item.truthy(currentAdjunct[item.dataIndex], currentAdjunct)}
                      </div>
                    </If>
                  </Col>
                </Row>
              </Col>
            );
          }
          const config = formMap[item.dataIndex] || formMap['default'];
          if (config.hide) return null;
          return (
            <Col span={config.rowSpan || 12} className="expense-invoice-cell">
              <Item {...formItemLayout} label={item.name} extra={config.extra}>
                {
                  getFieldDecorator(isMoreInfo ? `moreInfo-${item.dataIndex}` : item.dataIndex, {
                    rules: config.required
                      ? [{
                        required: true,
                        message: messages('expense-1.key732')/*请填写*/
                        }, ...(config.rules || [])]
                      : config.rules,
                    initialValue: isMoreInfo ? currentAdjunct[item.dataIndex] : this.getInitialValue(item.dataIndex)
                  })(React.createElement(isMoreInfo ? Input : config.component, isMoreInfo ? { maxLength: 150 } : config.props, config.children || null))
                }
              </Item>
            </Col>
          );
        })}
    </Row>;
  }

  render() {
    let {
      currentAdjunct, receiptChanges = {}, invoiceBase,
      currentAdjunct: { type, moreInfo = '{}', moreInfoLabel = '{}', fee, feeWithoutTax, tax, nonDeductibleAmount, pdfDamaged, receiptLabels, invoicedReceiptAmount, singleReimbursed, vatInvoiceCurrencyCode, invoiceTypeNo },
      receiptLabelsDesc = {}, isDetail, form: { getFieldDecorator }
    } = this.props;
    const { isEditing, buttonLoading, formMap, receiptTipImages } = this.state;
    const invoiceTypeNoValue = this.getFormItemValue('invoiceTypeNo') || invoiceTypeNo;
    const invoiceBaseState = isEditing ? this.invoiceBase : invoiceBase;
    moreInfo = moreInfo && JSON.parse(moreInfo);
    moreInfoLabel = moreInfoLabel && JSON.parse(moreInfoLabel);
    return (
      <section className={`${this.props.className} expense-invoice`} ref={'invoiceForm'}>
        <Spin spinning={buttonLoading}>
          <Form>
            <div className="expense-invoice-header">
              <div className="expense-invoice-header-title expense-invoice-top">
                {
                  isEditing
                    ? (
                      <Item>
                        {
                          getFieldDecorator('invoiceTypeNo', {
                            rules: (formMap.invoiceTypeNo || formMap.default).rules,
                            initialValue: { value: invoiceTypeNo, messageKey: type }
                          })(React.createElement((formMap.invoiceTypeNo || formMap.default).component, (formMap.invoiceTypeNo || formMap.default).props)
                          )
                        }
                      </Item>
                    )
                    : INVOICE_MAP.type.render(type, currentAdjunct, receiptChanges.invoiceTypeNo)
                }
                <div className="expense-invoice-header-title-right">
                  <If value={receiptTipImages[invoiceTypeNoValue] && isEditing}>
                    <Popover
                      placement="bottomRight"
                      overlayClassName="invoice-input-notes-popover"
                      overlayStyle={{ maxWidth: 'none', paddingBottom: 10 }}
                      content={<img style={{ width: '35vw' }} src={receiptTipImages[invoiceTypeNoValue]}/>}
                      getPopupContainer={() => document.getElementsByClassName('expense-invoice-desc')[0]}
                    >
                      <a className="expense-invoice-desc">{messages('expense-1.key166')/*填写说明*/}</a>
                    </Popover>
                  </If>
                  {
                    !isDetail &&
                    <Invoice.InvoiceOrigin
                      language={this.props.language}
                      origin={INVOICE_MAP['origin'].render('', currentAdjunct)}
                    />
                  }
                </div>
              </div>
              <div className="expense-invoice-header-amount expense-invoice-top">
                <If value={!isEditing}>
                   <span className="expense-invoice-header-total-amount">
                      {INVOICE_MAP.vatInvoiceCurrencyCode.render(vatInvoiceCurrencyCode, currentAdjunct, receiptChanges.vatInvoiceCurrencyCode)} {INVOICE_MAP.amount.render('', currentAdjunct)}
                   </span>
                </If>
                <span className="expense-invoice-used-amount">
                    {INVOICE_MAP.invoicedReceiptAmount.name} {INVOICE_MAP.invoicedReceiptAmount.render(invoicedReceiptAmount, currentAdjunct)}
                </span>
                <If value={!singleReimbursed}>
                  <img
                    className="expense-invoice-used-amount-icon"
                    src={doubt}
                    onClick={(e) => {
                      e.stopPropagation();
                      this.handleShowUsedMsg();
                    }}
                    alt={'doubt.png'}
                  />
                </If>
              </div>
              {!isEditing &&
              <div className="expense-invoice-used-amount expense-invoice-top">
                {
                  Object.keys({ fee, feeWithoutTax, tax, nonDeductibleAmount })
                    .map(item => INVOICE_MAP[item].isHide && INVOICE_MAP[item].isHide(currentAdjunct[item])
                      ? null
                      : <span>{item === 'feeWithoutTax' ? '（' : ''} {INVOICE_MAP[item].name}: {INVOICE_MAP[item].render(currentAdjunct[item], currentAdjunct, receiptChanges[item])} {item === 'feeWithoutTax' ? '，' : ''} {item === 'tax' ? ')' : ''}</span>)
                }
              </div>
              }
              <div className="expense-invoice-header-option expense-invoice-top">
                <Invoice.InvoiceLabels
                  labels={receiptLabels.filter(item => item.type !== 'HAND_RECODE_RECEIPT')}
                  pdfDamaged={pdfDamaged}
                  receiptChanges={receiptChanges}
                  receiptLabelsDesc={receiptLabelsDesc}
                />
                <div className="expense-invoice-header-buttons">
                  <If value={isEditing && !buttonLoading}>
                    <Button
                      size={'small'}
                      className="expense-invoice-right-button"
                      type={'default'}
                      onClick={this.handleCancel}
                    >
                      {messages('common.cancel')/*取消*/}
                    </Button>
                  </If>
                  <If value={this.isPrint() && !isEditing}>
                    <div className="expense-invoice-right-button">
                      <a onClick={this.handlePrint} type="link">{messages('common.print')/*打印*/}</a>
                    </div>
                  </If>

                  <If value={!isDetail}>
                    <div className="expense-invoice-right-button">
                      <a onClick={() =>this.props.handleShowMore(isEditing)} type="link">{ !isDetail && isEditing ? messages('expense-1.key733')/*更多编辑*/ : messages('common.view')/*查看*/}</a>
                    </div>
                  </If>
                  <If value={this.isEdit() && !isEditing}>
                    <Button
                      size={'small'}
                      icon={'edit'}
                      className="expense-invoice-right-button"
                      type={'primary'}
                      onClick={this.handleEdit}
                    >
                      {messages('common.edit')/*编辑*/}
                    </Button>
                  </If>
                  <If value={isEditing}>
                    <Button
                      size={'small'}
                      className="expense-invoice-right-button"
                      type={'primary'}
                      icon={'save'}
                      onClick={this.handleSave}
                    >
                      {messages('common.save')/*保存*/}
                    </Button>
                  </If>
                  <If value={this.isDelete()}>
                    <Button
                      size={'small'}
                      icon={'delete'}
                      className="expense-invoice-right-button"
                      type={'danger'}
                      onClick={this.handleDelete}
                    >
                      {messages('common.delete')/*删除*/}
                    </Button>
                  </If>
                </div>
              </div>
            </div>
            {
              invoiceBaseState.map(words => (
                words[0] &&
                <section className="expense-invoice-base">
                  {this.renderCell({
                    bodyWords: words.map(item => {
                      return {
                        ...INVOICE_MAP[item],
                        dataIndex: item
                      };
                    })
                  })}
                </section>
              ))
            }
            {(isEditing && ['payee', 'payeeNo', 'title', 'draweeNo'].some(item => currentAdjunct[item]) || !isEditing) && isDetail && moreInfo && moreInfoLabel && Object.keys(moreInfo).length > 0 &&
            <section className="expense-invoice-base">
              {this.renderCell({
                bodyWords:Object.keys(moreInfoLabel)
                  .map(item => {
                    return {
                      dataIndex: item,
                      name: moreInfoLabel[item],
                      render: (value, record, changes) => INVOICE_MAP.billingCode.render.call({}, value, record, changes)
                    };
                  }),
                moreInfo,
                isMoreInfo: true
              })}
            </section>
            }
          </Form>
          <If value={isDetail}>
            <Invoice.InvoiceGoods currentReceipt={currentAdjunct}/>
          </If>
        </Spin>
      </section>
    );
  }
}

function mapStateToProps(state) {
  return {
    user: state.login.user,
    company: state.login.company,
    documentaryCompany: state.login.documentaryCompany,
    language: state.main.language,
    profile: state.login.profile,
  };
}

Invoice.propTypes = {};

export default Invoice;
